package com.wn.common.net.support

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.wn.common.net.model.*
import okhttp3.Response
import retrofit2.Call
import retrofit2.Callback
import retrofit2.await
import retrofit2.awaitResponse
import java.io.IOException


/**
 * @Author: wn
 * @Date: 2023/1/12 16:29
 * @Description: okHttp3相关扩展
 */

// region okHttp3相关扩展
inline fun <reified T> okhttp3.Call.toLiveData(): LiveData<T?> {
  val live = MutableLiveData<T?>()
  enqueue(object : okhttp3.Callback {
    override fun onFailure(call: okhttp3.Call, e: IOException) {
      live.postValue(null)
    }

    override fun onResponse(call: okhttp3.Call, response: Response) {
      if (response.isSuccessful) {
        // response.toEntity<T>()
        live.postValue(response.toEntity<T>())
      }
    }
  })
  return live
}

/**
 * 将Response的对象，转化为需要的对象类型，也就是将 body.string转为 entity--T
 */
inline fun <reified T> Response.toEntity(): T? {
  if (!isSuccessful) return null
  if (T::class.java.isAssignableFrom(String::class.java))
    return runCatching {
      body?.string()
    }.getOrNull() as? T
  return runCatching {
    Gson().fromJson(body?.string(), T::class.java)
  }.onFailure {
    it.printStackTrace()
  }.getOrNull()
}
// endregion

// region retrofit相关扩展

/**
 * Retrofit的call执行异步，并转化为liveData可观察结果
 */
fun <T> Call<T>.toLiveData(): LiveData<T?> {
  val live = MutableLiveData<T?>()
  enqueue(object : Callback<T> {
    override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) {
      val value = if (response.isSuccessful) response.body() else null
      live.postValue(value)
    }

    override fun onFailure(call: Call<T>, t: Throwable) {
      live.postValue(null)
    }
  })
  return live
}

/**
 * 扩展retrofit的返回数据，调用await，并catch超时等异常
 */
suspend fun <T> Call<T>.serviceRsp(): ApiResponse {
  var result: ApiResponse = ApiEmptyResponse
  /*val response = */runCatching {
    awaitResponse()
  }
    .onFailure {
      result = ApiResponse.create(UNKNOWN_ERROR_CODE, it)
      it.printStackTrace()
    }/*.getOrThrow()*/
    .onSuccess {
      result = ApiResponse.create(it)
    }
  return result
}

/**
 * 扩展retrofit的返回数据，调用await，并catch超时等异常
 * @receiver Call<T>
 * @return DataResult<T> 返回格式为ApiResponse封装
 */
suspend fun <T : Any> Call<T>.serverData(): DataResult {
  var result: DataResult = Loading
  runCatching {
    await()
  }.onFailure {
    result = Error(RuntimeException(it))
    it.printStackTrace()
  }.onSuccess {
    result = Success(it)
  }
  return result
}
//endregion